package org.xbdframework.dao.core.support;

import javax.sql.DataSource;

import org.springframework.beans.BeansException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.Assert;

import org.xbdframework.dao.PageHelper;
import org.xbdframework.jdbc.core.support.JdbcDaoBeanPostProcessor;

/**
 * {@link org.springframework.beans.factory.config.BeanPostProcessor}接口实现，用以
 * 为属性{@code DataSource}、{@code JdbcTemplate}、{@code NamedParameterJdbcTemplate}、
 * {@code PageHelper}、{@code showSql}自动化赋值.
 * <p>
 * 属性 {@code showSql}可以为{@code null}, 此时，框架将会使用默认值.
 * <p>
 * {@code DataSource} 和 {@code JdbcTemplate} 任选其一赋值。
 * 如均赋值，{@link org.springframework.jdbc.core.support.JdbcDaoSupport}会做判断逻辑，
 * 判断{@code DataSource} 和 {@code JdbcTemplate}中的{@code DataSource}是否相同，如不相同，
 * 会舍弃为其赋值的{@code JdbcTemplate}，从而基于{@code DataSource}创建新的{@code JdbcTemplate}.
 * <p>
 * {@code TradeJdbcDaoBeanPostProcessor}已囊括{@link JdbcDaoBeanPostProcessor}的自动化赋值逻辑，
 * 即会自动化为属性{@code DataSource}、{@code JdbcTemplate}、{@code NamedParameterJdbcTemplate}赋值，
 * 而无需再重复注册{@code JdbcDaoBeanPostProcessor}实例.
 * <p>
 * 注意: 属性 {@code NamedParameterJdbcTemplate}可以为{@code null}, 此时，框架
 * 将会基于{@code JdbcTemplate}.
 *
 * @author 刘明磊
 * @since 4.3
 * @see org.springframework.beans.factory.config.BeanPostProcessor
 * @see JdbcDaoBeanPostProcessor
 * @see org.springframework.jdbc.core.support.JdbcDaoSupport
 * @see XbdJdbcDaoSupport
 */
public class XbdJdbcDaoBeanPostProcessor extends JdbcDaoBeanPostProcessor {

	private PageHelper pageHelper;

	private Boolean showSql;

	public XbdJdbcDaoBeanPostProcessor(DataSource dataSource, PageHelper pageHelper) {
		super(dataSource);
		this.pageHelper = pageHelper;
	}

	public XbdJdbcDaoBeanPostProcessor(JdbcTemplate jdbcTemplate, PageHelper pageHelper) {
		super(jdbcTemplate);
		this.pageHelper = pageHelper;
	}

	public XbdJdbcDaoBeanPostProcessor(JdbcTemplate jdbcTemplate,
			NamedParameterJdbcTemplate namedParameterJdbcTemplate,
			PageHelper pageHelper) {
		this(jdbcTemplate, namedParameterJdbcTemplate, pageHelper, null);
	}

	public XbdJdbcDaoBeanPostProcessor(JdbcTemplate jdbcTemplate,
			NamedParameterJdbcTemplate namedParameterJdbcTemplate, PageHelper pageHelper,
			Boolean showSql) {
		super(jdbcTemplate, namedParameterJdbcTemplate);
		this.pageHelper = pageHelper;
		this.showSql = showSql;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		super.afterPropertiesSet();

		Assert.notNull(this.pageHelper, "pageHelper is required.");
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		if (bean instanceof XbdJdbcDaoSupport) {
			if (getDataSource() != null) {
				((XbdJdbcDaoSupport) bean).setDataSource(getDataSource());
			}

			if (getJdbcTemplate() != null) {
				((XbdJdbcDaoSupport) bean).setJdbcTemplate(getJdbcTemplate());
			}

			if (getNamedParameterJdbcTemplate() != null) {
				((XbdJdbcDaoSupport) bean)
						.setNamedParameterJdbcTemplate(getNamedParameterJdbcTemplate());
			}

			((XbdJdbcDaoSupport) bean).setPageHelper(this.pageHelper);

			if (this.showSql != null) {
				((XbdJdbcDaoSupport) bean).setShowSql(this.showSql);
			}
		}
		else {
			super.postProcessBeforeInitialization(bean, beanName);
		}

		return bean;
	}

	public PageHelper getPageHelper() {
		return pageHelper;
	}

	public void setPageHelper(PageHelper pageHelper) {
		this.pageHelper = pageHelper;
	}

	public Boolean getShowSql() {
		return showSql;
	}

	public void setShowSql(Boolean showSql) {
		this.showSql = showSql;
	}

}
